﻿// App Part Communication Framework - static methods
var APCF = APCF || {
    MessageTypes: {
        Registration: {
            TYPE: "APCFRegisterAppPartType",
            INSTANCE: "APCFRegisterAppPartInstance",
            TYPELOADSUCCESS: "APCFRegisterAppPartTypeConfirmation",
            INSTANCELOADSUCCESS: "APCFRegisterAppPartInstanceConfirmation"
        }
    },

    initialiseAppPartPage: function() {
        jQuery(document).ready(function () { 
            window.attachEvent('onmessage', APCF.processMessage); 
            window.setTimeout(registerType, 0);
        });
    },

    processMessage: function (message) {
        // is the message valid?
        var messageObject = JSON.parse(message.data);

        if (!messageObject.messageType || messageObject.messageType.substring(0, 4) != "APCF") return;
        switch (messageObject.messageType) {
            case "APCFRegisterAppPartType": { APCF.registerAppPartType(messageObject); break; }
            case "APCFRegisterAppPartInstance": { APCF.registerAppPartInstance(messageObject); break; }
            case "APCFRegisterAppPartTypeConfirmation": { registerInstance(); ('t: ' + window.location.href); break; }
            case "APCFRegisterAppPartInstanceConfirmation": { ('i: ' + window.location.href); break; }
        }
    },

    confirmAppPartTypeRegistration: function (appPartType) {
        var message = new Object();
        message.messageType = "APCFRegisterAppPartTypeConfirmation";
        appPartType.iframe.contentWindow.postMessage(JSON.stringify(message), "*");
    },

    confirmAppPartInstanceRegistration: function (appPartObject) {
        var message = new Object();
        message.messageType = "APCFRegisterAppPartInstanceConfirmation";
        appPartObject.iframe.contentWindow.postMessage(JSON.stringify(message), "*");
    },

    // Register a new app part type - will be called multiple times if the same app part
    // is loaded on the page more than once
    registerAppPartType: function (appPartType) {
        if (!appPartType.typeAsText) return;
        APCF.appPartTypes.forEach(
            function (elem, index, array) {
                if (elem.typeAsText == appPartType.typeAsText) return;
            });
        APCF.appPartTypes.push(appPartType);
        //alert('loading ' + appPartType.scriptUrl);
        if (window[appPartType.typeAsText] == null) {
            jQuery.ajax({
                url: appPartType.scriptUrl,
                dataType: 'script',
                async: false
            });
        }
        APCFAppPartType.loadiframe(appPartType);
        APCF.confirmAppPartTypeRegistration(appPartType);
    },

    // Register a new app part instance
    registerAppPartInstance: function (appPartObject) {
        // to do - validate app: type and sender id
        // decode sender id into frame id
        var app = this.createAppPartInstance(appPartObject);
        window.setTimeout(app.initialise_base.bind(app), 0);
        APCF.confirmAppPartInstanceRegistration(app)
    },

    createAppPartInstance: function (appPartObject) {
        var appPartInstance = null;
        APCF.appPartTypes.every(
            function (elem, index, array) {
                if (elem.typeAsText.toString() == appPartObject.typeAsText.toString()) {
                    appPartInstance = new window[elem.typeAsText](appPartObject);
                    return false;
                }
            });
        return appPartInstance;

    }
};

APCF.appPartTypes = [];

// APCF App Type
function APCFAppPartType(messageType, typeAsText, scriptUrl, senderId) {
    this.messageType = messageType;
    this.typeAsText = typeAsText;
    this.scriptUrl = scriptUrl;
    this.senderId = senderId;
}

APCFAppPartType.loadiframe = function (appPartType) {
    var senderIndex = appPartType.senderId.substring(8);
    var iframeId = unescape(spAppIFrameSenderInfo[senderIndex][1]);
    /*var senderOrigin = unescape(spAppIFrameSenderInfo[senderIndex][2]);
    if (senderId != spAppIFrameSenderInfo[senderIndex][0] || senderOrigin != e.origin)
        return;*/

    var iframe = document.getElementById(iframeId);
    if (null != iframe)
        appPartType.iframe = iframe;
}

APCFAppPartType.prototype.messageType = "Invalid";
APCFAppPartType.prototype.typeAsText = "Invalid";
APCFAppPartType.prototype.scriptUrl = "Invalid";
APCFAppPartType.prototype.senderId = "Invalid";

// APCF App Instance
function APCFAppPartInstance(app) {
    if (app == null) return;
    this.appPartData = app;

    var senderIndex = app.senderId.substring(8);
    var iframeId = unescape(spAppIFrameSenderInfo[senderIndex][1]);
    /*var senderOrigin = unescape(spAppIFrameSenderInfo[senderIndex][2]);
    if (senderId != spAppIFrameSenderInfo[senderIndex][0] || senderOrigin != e.origin)
        return;*/

    var iframe = document.getElementById(iframeId);
    if (null != iframe)
        this.iframe = iframe;

    this.divRoot = iframe.parentElement.parentElement;
}

APCFAppPartInstance.prototype.initialise_base = function () {

    this.iframe.style.display = "none";
    // .ms-webpartzone-cell has a margin - if nothing is displayed then we need to remove the margin (s4-wpcell-plain ms-webpartzone-cell ms-webpart-cell-vertical ms-fullWidth)
    this.divRoot.style.width = "";
    this.divRoot.style.height = "";

    if (this.initialise)
        this.initialise();

    window.setTimeout(this.load_base.bind(this), 0);
}
APCFAppPartInstance.prototype.load_base = function () { if (this.load) this.load(); window.setTimeout(this.render_base.bind(this), 0); }
APCFAppPartInstance.prototype.render_base = function () { if (this.render) this.render(); }
APCFAppPartInstance.prototype.messageType = "Invalid";
APCFAppPartInstance.prototype.origin = "Invalid";
APCFAppPartInstance.prototype.senderId = "Invalid";
APCFAppPartInstance.prototype.typeAsText = "Invalid";

// Register handler
// to do - ensure only registered once
jQuery(document).ready(function () { window.attachEvent('onmessage', APCF.processMessage); });
